package com.yh.util;

import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import com.yh.annotation.Id;

import java.sql.Connection;

/**
 * JDBC 工具类 提供数据库连接和关闭的工具类
 * 
 * @author 湛锋
 *
 */
public class DBUtil {

	/**
	 * 构造方法私有化，无例模式
	 */
	private DBUtil() {
	}

	private static String driverName;
	private static String url;
	private static String root;
	private static String password;

	static {
		try {
			Properties config = new Properties();
			// getResourceAsStream()默认则从ClassPath根下获取资源
			config.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties"));

			String className = driverName = config.getProperty("jdbc.driverName");
			url = config.getProperty("jdbc.url");
			root = config.getProperty("jdbc.root");
			password = config.getProperty("jdbc.password");

			Class.forName(className);
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(0);
		}
	}

	/**
	 * 获取数据库连接
	 * 
	 * @return 数据连接
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException {
		return DriverManager.getConnection(url, root, password);
	}

	/**
	 * 关闭数据库连接和关闭预编译语句对象
	 * 
	 * @param conn
	 * @param stmt
	 */
	public static void close(Connection conn, Statement stmt) {
		try {
			stmt.close();
			conn.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 关闭数据库连接、关闭预编译语句对象、关闭数据结果集
	 * 
	 * @param conn
	 * @param stmt
	 * @param rs
	 */
	public static void close(Connection conn, Statement stmt, ResultSet rs) {
		try {
			rs.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		close(conn, stmt);
	}

	/**
	 * 设置预编译语句的所有参数
	 * 
	 * @param pstmt
	 * @param objects
	 * @throws SQLException
	 */
	public static void setParams(PreparedStatement pstmt, Object... objects) throws SQLException {
		for (int i = 0; i < objects.length; i++) {
			pstmt.setObject(i + 1, objects[i]);
		}
	}

	/**
	 * 查询数据库获取结果集的第一行第一列的数据
	 * 
	 * @param sql
	 * @param args
	 * @return
	 * @throws SQLException
	 */
	public static long getLong(String sql, Object... args) throws SQLException {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			conn = getConnection();
			pstmt = conn.prepareStatement(sql);
			setParams(pstmt, args);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				return rs.getLong(1);
			} else {
				throw new SQLException("没有发现一条记录");
			}
		} finally {
			close(conn, pstmt, rs);
		}
	}

	/**
	 * 判断是否是主键
	 * 
	 * @param cls
	 * @param prop
	 * @return
	 * @throws SQLException
	 */
	public static boolean isId(Class<?> cls, PropertyDescriptor prop) throws SQLException {
		if (prop.getReadMethod() != null && prop.getReadMethod().isAnnotationPresent(Id.class)) {
			return true;
		} else if (prop.getWriteMethod() != null && prop.getWriteMethod().isAnnotationPresent(Id.class)) {
			return true;
		} else {
			Field f = null;
			try {
				f = cls.getDeclaredField(prop.getName());
			} catch (Exception e) {
			}
			if(f!=null && f.isAnnotationPresent(Id.class)) {
				return true;
			}
		}
		return false;
	}
	
	
}
